package com.shop.cereshop.app.controller.recommend;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.shop.cereshop.app.annotation.NoRepeatSubmit;
import com.shop.cereshop.app.annotation.NoRepeatWebLog;
import com.shop.cereshop.app.config.ConstantProperties;
import com.shop.cereshop.app.dao.recommend.RecommendAtUserDAO;
import com.shop.cereshop.app.page.buyer.UserDetailVO;
import com.shop.cereshop.app.page.recommend.AllSearchVO;
import com.shop.cereshop.app.page.recommend.RecommendPageVO;
import com.shop.cereshop.app.page.recommend.RecommendTypeVO;
import com.shop.cereshop.app.param.recommend.*;
import com.shop.cereshop.app.service.buyer.CereBuyerUserService;
import com.shop.cereshop.app.service.recommend.*;
import com.shop.cereshop.app.tencent.moderation.service.ContentCheckService;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.common.PageParam;
import com.shop.cereshop.commons.domain.recommend.CereRecommendDraft;
import com.shop.cereshop.commons.domain.recommend.CereRecommendType;
import com.shop.cereshop.commons.domain.recommend.RecommendAtUser;
import com.shop.cereshop.commons.enums.recommend.RecommendPublishEnum;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.service.im.ImUserService;
import com.shop.cereshop.commons.tencent.moderation.constant.ModerationConstant;
import com.shop.cereshop.commons.tencent.moderation.domain.request.CreateVideoModerationTaskParam;
import com.shop.cereshop.commons.tencent.moderation.domain.response.VideoModerationResult;
import com.shop.cereshop.commons.tencent.moderation.service.VideoModerationService;
import com.shop.cereshop.commons.utils.GsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("recommends")
@Slf4j(topic = "RecommendNewController")
@Api(value = "动态新模块", tags = "动态新模块")
public class RecommendNewController {

    @Autowired
    private CereRecommendTypeService cereRecommendTypeService;
    @Autowired
    private CereRecommendTrendsService cereRecommendTrendsService;
    @Autowired
    private CereRecommendCommentService cereRecommendCommentService;
    @Autowired
    private CereRecommendLikesService cereRecommendLikesService;
    @Autowired
    private CereUserBlockService cereUserBlockService;
    @Resource
    private CereRecommendDraftService cereRecommendDraftService;
    @Resource(name = "ImUserService")
    private ImUserService imUserService;
    @Resource
    private CereBuyerUserService cereBuyerUserService;
    @Resource
    private RecommendAtUserDAO recommendAtUserDAO;
    @Resource
    private RecommendAtUserService recommendAtUserService;
    @Resource
    private ContentCheckService contentCheckService;
    @Resource
    private VideoModerationService videoModerationService;

    @PostMapping(value = "hotRecommendTypes")
    @ApiOperation(value = "获取热门话题列表")
    public Result<List<RecommendTypeVO>> getHotRecommendType(@RequestBody @NotNull(message = "参数不能为空") RecommendTypeDTO param, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");

        return Result.success(cereRecommendTypeService.getHotRecommendType(param, user));
    }

    @GetMapping(value = "getRecommends")
    @ApiOperation(value = "获取动态分页")
    public Result<Page<RecommendPageVO>> getRecommendPage(@ModelAttribute RecommendPageDTO param, HttpServletRequest request) throws CoBusinessException {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        return Result.success(cereRecommendTrendsService.getRecommendPage(param, user));
    }

    /**
     * 话题详情查询
     *
     * @return
     */
    @GetMapping(value = "getType")
    @ApiOperation(value = "话题详情查询")
    public Result<RecommendTypeVO> getRecommendType(@RequestParam("recommendTypeId")
                                                    @NotNull(message = "参数不能为空")
                                                    @ApiParam(value = "话题id", required = true) Long recommendTypeId) {
        return new Result(cereRecommendTypeService.getRecommendType(recommendTypeId), CoReturnFormat.SUCCESS);
    }


    /**
     * 动态详情查询
     *
     * @return
     */
    @GetMapping(value = "getRecommend")
    @ApiOperation(value = "动态详情查询")
    public Result<RecommendPageVO> getRecommendDetail(@NotNull(message = "参数不能为空") @RequestParam("recommendId") Long recommendId, HttpServletRequest request) {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result(CoReturnFormat.USER_NOT_LOGIN);
        }
        return new Result<>(cereRecommendTrendsService.getRecommendDetail(recommendId, user), CoReturnFormat.SUCCESS);
    }

    /**
     * 点赞
     *
     * @return
     */
    @PostMapping(value = "/likes/like")
    @NoRepeatSubmit
    @ApiOperation(value = "动态点赞")
    public Result commentPage(@Validated @RequestBody RecommendLikesParam param, HttpServletRequest request) throws CoBusinessException {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        param.setUserId(user.getBuyerUserId());
        //        判断该用户是否可以点赞动态
        if (user.getIfAllowOther() == 0) {
            return new Result(CoReturnFormat.NOT_ALLOW_LIKE_DYNAMIC);
        }
        Integer like = cereRecommendLikesService.like(param);
        if (like > 0) {
            return new Result(CoReturnFormat.SUCCESS);
        } else {
            return new Result(CoReturnFormat.FAIL);
        }

    }

    /**
     * 评论点赞
     */
    @PostMapping(value = "/comment/likes/like")
    @NoRepeatSubmit
    @ApiOperation(value = "评论点赞")
    public Result commentLikesLike(@Validated @RequestBody RecommendLikesParam param, HttpServletRequest request) throws CoBusinessException {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        param.setUserId(user.getBuyerUserId());
        param.setUserName(user.getName());
        //        判断该用户是否可以点赞动态
        if (user.getIfAllowOther() == 0) {
            return new Result(CoReturnFormat.NOT_ALLOW_LIKE_DYNAMIC);
        }

        Integer like = cereRecommendLikesService.commentLikesLike(param);
        if (like > 0) {
            return new Result(CoReturnFormat.SUCCESS);


        } else {
            return new Result(CoReturnFormat.FAIL);
        }
    }


    /**
     * 分享
     *
     * @return
     */
    @GetMapping(value = "/trend/share")
    @ApiOperation(value = "分享")
    public Result share(@Validated Long recommendId, HttpServletRequest request) {
        //获取当前登录账户
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        cereRecommendTrendsService.share(recommendId);
        return new Result(user.getName(), "分享", GsonUtil.objectToGson(recommendId));
    }

    @NoRepeatSubmit
    @DeleteMapping(value = "delete")
    @ApiOperation(value = "删除动态")
    public Result deleteRecommend(@NotNull(message = "参数不为空") @RequestParam("recommendId") Long recommendId, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        Integer number = cereRecommendTrendsService.deleteRecommend(recommendId, user.getBuyerUserId());

        if (number > 0) {
            return new Result(CoReturnFormat.SUCCESS);
        }

        return new Result(CoReturnFormat.FAIL);
    }

    @PostMapping("draft/update")
    @ApiOperation("更新草稿")
    public Result<Void> saveDraft(@NotNull(message = "参数不为空") @RequestBody RecommendSaveDTO param, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        CereRecommendDraft cereRecommendDraft = BeanUtil.copyProperties(param, CereRecommendDraft.class);

        //设置用户信息
        cereRecommendDraft.setBuyerUserId(user.getBuyerUserId());

        //设置草稿所属话题id
        String recommendTypeIds = param.getRecommendTypeIdList()
                .stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        cereRecommendDraft.setRecommendTypeIds(recommendTypeIds);
        boolean result = cereRecommendDraftService.saveOrUpdate(cereRecommendDraft);

        //异步插入@信息
        List<RecommendAtUser> recommendAtUserList = new ArrayList<>();
        //保存@的消息
        if (param.getAtUser() != null) {
            param.getAtUser().forEach(dto -> {
                RecommendAtUser recommendAtUser = new RecommendAtUser();
                recommendAtUser.setAtUserId(dto.getUserId());
                recommendAtUser.setAtUsername(dto.getName());
                recommendAtUser.setAtTargetId(cereRecommendDraft.getDraftId());
                recommendAtUser.setBuyerUserId(user.getBuyerUserId());
                recommendAtUser.setAtType(3);
                recommendAtUserList.add(recommendAtUser);
            });
        }
        //批量插入@信息操作
        if (CollectionUtil.isNotEmpty(recommendAtUserList)) {
            recommendAtUserService.saveBatch(recommendAtUserList);
        }
        return result ? Result.success() : Result.failed(CoReturnFormat.FAIL);
    }


    @GetMapping("draft/get/list")
    @ApiOperation("获取草稿箱列表")
    public Result<Page<RecommendPageVO>> getDraftPage(@NotNull(message = "参数不为空") @ModelAttribute PageParam param, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_BUYER);
        }
        return Result.success(cereRecommendDraftService.getDraftPage(param, user));
    }

    @GetMapping("draft/get")
    @ApiOperation("获取草稿箱详情")
    public Result<RecommendPageVO> getDraftById(@NotNull(message = "参数不为空") @RequestParam("draftId") Long draftId) {
        RecommendPageVO result = cereRecommendDraftService.getDraftDetailById(draftId);
        return Result.success(result);
    }

    @GetMapping("user/search")
    @ApiOperation(value = "搜索获取用户列表")
    public Result<Page<UserDetailVO>> getUserDetailList(@ModelAttribute @NotNull(message = "参数不为空") RecommendPageDTO param, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        Page<UserDetailVO> result = cereBuyerUserService.getUserDetailList(param, user);
        return new Result<>(result, CoReturnFormat.SUCCESS);
    }

    @PostMapping("updateBlock")
    @ApiOperation(value = "更新屏蔽操作")
    @NoRepeatSubmit
    @NoRepeatWebLog
    public Result updateBlock(@RequestBody CereUserBlockDTO param, HttpServletRequest request) throws CoBusinessException {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        cereUserBlockService.updateBlock(param, user);
        return new Result<>(CoReturnFormat.SUCCESS);
    }

    @PostMapping("type/save")
    @ApiOperation(value = "添加话题")
    @NoRepeatSubmit
    @NoRepeatWebLog
    public Result addRecommendType(@RequestBody CereRecommendType param) {
        return cereRecommendTypeService.addRecommendType(param) > 0 ? new Result<>(CoReturnFormat.SUCCESS) : new Result<>(CoReturnFormat.FAIL);
    }

    @PutMapping("pinned/update")
    @ApiOperation(value = "修改置顶")
    public Result updatePinned(@NotNull(message = "参数不为空") @RequestParam("recommendId") @ApiParam(value = "动态id", required = true) Long recommendId,
                               @NotNull(message = "参数不为空") @RequestParam @ApiParam(value = "是否置顶", required = true) Boolean pinned,
                               HttpServletRequest request) throws CoBusinessException {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result(CoReturnFormat.USER_NOT_LOGIN);
        }
        cereRecommendTrendsService.updatePinned(recommendId, pinned, user.getBuyerUserId());
        return new Result(CoReturnFormat.SUCCESS);
    }

    @GetMapping("collectAndLike/list")
    @ApiOperation(value = "获取个人中心收藏和赞过的动态")
    public Result<Page<RecommendPageVO>> getCollectAndLikePage(@NotNull(message = "参数不为空") @ModelAttribute RecommendLikeDTO param,
                                                               HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        Page<RecommendPageVO> result = cereRecommendTrendsService.getCollectAndLikePage(param, user);
        return new Result<>(result, CoReturnFormat.SUCCESS);
    }

    @PostMapping(value = "update")
    @ApiOperation(value = "修改动态")
    @NoRepeatSubmit
    @NoRepeatWebLog
    public Result saveRecommend(@NotNull(message = "参数不为空") @RequestBody RecommendSaveDTO param, HttpServletRequest request) throws CoBusinessException {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        }
        if (user.getIfAllowTrends() == 0) {
            return new Result(CoReturnFormat.NOT_ALLOW_PUBLISH_DYNAMIC);
        }
        if (StringUtils.isBlank(param.getRemark()) && CollUtil.isEmpty(param.getFileUrlList()) && StringUtils.isBlank(param.getFileUrl())){
            return Result.failed(CoReturnFormat.FAIL, "请上传图片或视频或文字内容!");
        }

        // 默认审核状态为通过
        int publishStatus = RecommendPublishEnum.AUDIT_SUCCESS.getCode();
        StringBuilder errorMsg = new StringBuilder();
        if (Boolean.TRUE.equals(ConstantProperties.OPEN_TENCENT_MODERATION)) {
            // 审核动态文案 检查是否违规
            if (StringUtils.isNotBlank(param.getRemark())) {
                Result<Object> textCheckResult = contentCheckService.checkTextContent(param.getRemark());
                if (!CoReturnFormat.SUCCESS.equals(textCheckResult.getCode())) {
                    publishStatus = RecommendPublishEnum.UNAUDITED.getCode();
                    errorMsg.append("动态文案违规;");
                }
            }

            // 多张图片批量审核 检查是否违规
            if (param.getFileType() == 1 && CollUtil.isNotEmpty(param.getFileUrlList())) {
                Result<Object> batchImageCheckResult = contentCheckService.checkBatchImages(param.getFileUrlList());
                if (!CoReturnFormat.SUCCESS.equals(batchImageCheckResult.getCode())) {
                    publishStatus = RecommendPublishEnum.UNAUDITED.getCode();
                    errorMsg.append("图片违规;");
                }
            }

            // 视频和视频封面审核
            if (param.getFileType() == 2) {
                // 审核视频封面
                if (StringUtils.isNotBlank(param.getCover())) {
                    Result<Object> coverCheckResult = contentCheckService.checkTextContent(param.getCover());
                    if (!CoReturnFormat.SUCCESS.equals(coverCheckResult.getCode())) {
                        publishStatus = RecommendPublishEnum.UNAUDITED.getCode();
                        errorMsg.append("视频封面违规;");
                    }
                }

                // 创建视频审核任务
                if (StringUtils.isNotBlank(param.getFileUrl())){
                    CreateVideoModerationTaskParam createTaskParam = new CreateVideoModerationTaskParam();
                    createTaskParam.setVideoUrl(param.getFileUrl());
                    createTaskParam.setEnabledCallback(true);
                    VideoModerationResult taskResult = videoModerationService.createModerationTask(createTaskParam);
                    if (taskResult != null && taskResult.isSuccess()) {
                        param.setTaskId(taskResult.getTaskId());
                        param.setTaskStatus(taskResult.getStatus());
                    }
                    publishStatus = RecommendPublishEnum.UNAUDITED.getCode();
                }
            }
        }

        // 保存动态并设置审核状态
        int number = cereRecommendTrendsService.saveRecommend(param, user, publishStatus);
        // 如果是待人工审核状态，返回相应提示
        if (publishStatus == RecommendPublishEnum.UNAUDITED.getCode()) {
            return Result.success(CoReturnFormat.SUCCESS, errorMsg + "已进入人工审核，请耐心等待审核结果!");
        }
        return number > 0 ? new Result<>(CoReturnFormat.SUCCESS) : new Result<>(CoReturnFormat.FAIL);
    }



//    @PostMapping(value = "conceren/get")
//    @ApiOperation("获取个人关注动态列表")
//    public Result<Page<RecommendPageVO>> getMyConcernRecommends (@RequestBody PageParam param, HttpServletRequest request) {
//        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
//        if (user == null) {
//            return new Result<>(CoReturnFormat.USER_NOT_LOGIN);
//        }
//        return Result.success(cereRecommendTrendsService.getMyConcernRecommends(param, user));
//    }

    @GetMapping(value = "all/search")
    @ApiOperation("宠圈全部搜索接口")
    public Result<AllSearchVO> getAllSearch(@ModelAttribute @NotNull(message = "参数不为空") RecommendPageDTO param, HttpServletRequest request) {
        CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
        if (user == null) {
            return Result.failed(CoReturnFormat.USER_NOT_LOGIN);
        }
        return Result.success(cereRecommendTrendsService.getAllSearch(param, user));
    }

    @GetMapping(value = "addRecommendFootPrint")
    @ApiOperation("添加动态足迹")
    public Result addRecommendFootPrint(@NotNull(message = "参数不为空") @RequestParam("recommendId") Long recommendId, HttpServletRequest request) {
        try {
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            cereRecommendTrendsService.addFootPrint(recommendId, user);
        } catch (Exception e) {
            log.error("添加动态足迹异常");
        }
        return new Result(CoReturnFormat.SUCCESS);
    }


}
